//
//  UCCusterManager.m
//  SDK开发版本
//
//  Created by 北京国泰北斗科技有限公司 on 2017/3/21.
//  Copyright © 2017年 北京国泰北斗科技有限公司. All rights reserved.
//

#import "UCClusterManager.h"
#import "GMUMarkerClustering.h"
#import "UCMarker.h"
#import "UCClusterItem.h"
#import <objc/runtime.h>
#import <GoogleMaps/GoogleMaps.h>

@interface UCClusterManager ()<GMUClusterManagerDelegate,GMSMapViewDelegate,GMUClusterRendererDelegate>{
    __weak UCMapView *_mapView;
    NSString *_itemClass;
    GMUDefaultClusterRenderer<GMUClusterRenderer> *_renderer;
}
@property(nonatomic,strong)GMUClusterManager *gmManager;
@end

@implementation UCClusterManager

- (instancetype)initWithMap:(UCMapView *)mapView
            initWithBuckets:(NSArray<NSNumber *> *)buckets
           backgroundImages:(NSArray<UIImage *> *)backgroundImages{
    
    self = [super init];
    if (self) {
        //设置默认样式
        id<GMUClusterIconGenerator> iconGenerator;
        id<GMUClusterAlgorithm> algorithm = [[GMUNonHierarchicalDistanceBasedAlgorithm alloc] init];
        if (backgroundImages.count > 0 && buckets.count > 0){
            iconGenerator = [[GMUDefaultClusterIconGenerator alloc] initWithBuckets:buckets
                                                                   backgroundImages:backgroundImages];
        }else{
            iconGenerator = [[GMUDefaultClusterIconGenerator alloc] init];
        }
        _mapView = mapView;
        _renderer= [[GMUDefaultClusterRenderer alloc] initWithMapView:[_mapView valueForKey:@"map"] clusterIconGenerator:iconGenerator];
        _renderer.delegate = self;
        self.gmManager = [[GMUClusterManager alloc] initWithMap:[mapView valueForKey:@"map"] algorithm:algorithm renderer:_renderer];
    }
    return self;
}

- (void)setDelegate:(id<UCClusterManagerDelegate>)delegate mapDelegate:(id<UCMapViewDelegate>)mapDelegate{
    _delegate = delegate;
    _mapDelegate = mapDelegate;
    [self.gmManager setDelegate:self mapDelegate:self];
}

- (void)addItem:(id<UCClusterItem>)item{
    [self.gmManager addItem:(id<GMUClusterItem>)item];
}

- (UCMarker *)updateItem:(id<UCClusterItem>)item{
    id<GMUClusterItem> gmItem = (id<GMUClusterItem>)item;
    NSMutableSet<GMUClusterItem> *set = [self renderedClusterItems];
    NSArray *array = [set valueForKey:@"itemKey"];
    NSArray *markers = [self itemMarkers];
    
    UCMarker *myMarker = nil;
    if ([array containsObject:gmItem.itemKey]) {
        for (GMSMarker *marker in markers) {
            NSString *itemKey = [(id<GMUClusterItem>)marker.userData itemKey];
            if ([itemKey isEqualToString:gmItem.itemKey]) {
                myMarker = [UCMarker markerWithPosition:marker.position];
                [myMarker setValue:marker forKey:@"marker"];
                continue ;
            }
        }
    }
    return myMarker;
}

- (GMSMarker *)renderer:(id<GMUClusterRenderer>)renderer markerForObject:(id)object{
    // 如果实现了这个协议，那就是展开的点
    if ([object conformsToProtocol:@protocol(UCClusterItem)]) {
        if ([_delegate respondsToSelector:@selector(clusterManager:userData:)]) {
            UCMarker *myMarker = [_delegate clusterManager:self userData:object];
            return [myMarker valueForKey:@"marker"];
        }
    }
    return nil;
}

- (void)changeItemIcon:(id<UCClusterItem>)item icon:(UIImage *)icon groundAnchor:(CGPoint)groundAnchor{
    NSArray *markers = [self itemMarkers];
    for (GMSMarker *marker in markers) {
        NSString *itemKey = [(id<GMUClusterItem>)marker.userData itemKey];
        if ([itemKey isEqualToString:item.itemKey]) {
            marker.icon = icon;
            marker.groundAnchor = groundAnchor;
            break;
        }
    }
}

- (void)addItems:(NSArray<id<UCClusterItem>> *)items{
    
    [_gmManager addItems:(NSArray<id<GMUClusterItem>> *)items];
}

- (void)removeItem:(id<UCClusterItem>)item{

    [_gmManager removeItem:(id<GMUClusterItem>)item];
}

- (void)clearItems{
    [_gmManager clearItems];
}

- (void)cluster{
    [_gmManager cluster];
}

#pragma mark - 私有函数
- (NSMutableSet<GMUClusterItem> *)renderedClusterItems{
    return [_renderer valueForKey:@"_renderedClusterItems"];
}
- (NSArray *)itemMarkers{
    return [_renderer valueForKey:@"_itemMarkers"];
}

#pragma mark - 代理方法
- (NSString *)selectedMarker{
    if ([self.delegate respondsToSelector:@selector(selectedMarker)]) {
        return [self.delegate selectedMarker];
    }
    return nil;
}
- (BOOL)clusterManager:(GMUClusterManager *)clusterManager didTapCluster:(id<GMUCluster>)cluster{
    if ([_delegate respondsToSelector:@selector(clusterManager:didTapCluster:)]) {
        return [_delegate clusterManager:self didTapCluster:(id<UCCluster>)cluster];
    }
    return NO;
}

- (BOOL)clusterManager:(GMUClusterManager *)clusterManager didTapClusterItem:(id<GMUClusterItem>)clusterItem{
    if ([_delegate respondsToSelector:@selector(clusterManager:didTapClusterItem:)]) {
        return [_delegate clusterManager:self didTapClusterItem:(id<UCClusterItem>)clusterItem];
    }
    return NO;
}

- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:didTapAtCoordinate:)]) {
        [self.mapDelegate mapView:_mapView didTapAtCoordinate:coordinate];
    }
}

- (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:willMove:)]) {
        [self.mapDelegate mapView:_mapView willMove:gesture];
    }
}

- (void)mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:didLongPressAtCoordinate:)]) {
        [self.mapDelegate mapView:_mapView didLongPressAtCoordinate:coordinate];
    }
}

- (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:didTapInfoWindowOfMarker:)]) {
        UCMarker *mmarker = [UCMarker markerWithPosition:marker.position];
        [mmarker setValue:marker forKey:@"marker"];
        [self.mapDelegate mapView:_mapView didTapInfoWindowOfMarker:mmarker];
    }
}
- (void)mapView:(GMSMapView *)mapView didLongPressInfoWindowOfMarker:(GMSMarker *)marker{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:didLongPressInfoWindowOfMarker:)]) {
        UCMarker *mmarker = [UCMarker markerWithPosition:marker.position];
        [mmarker setValue:marker forKey:@"marker"];
        [self.mapDelegate mapView:_mapView didLongPressInfoWindowOfMarker:mmarker];
    }
}
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:markerInfoWindow:)]) {
        UCMarker *mmarker = [UCMarker markerWithPosition:marker.position];
        [mmarker setValue:marker forKey:@"marker"];
        return [self.mapDelegate mapView:_mapView markerInfoWindow:mmarker];
    }
    return nil;
}
- (UIView *)mapView:(GMSMapView *)mapView markerInfoContents:(GMSMarker *)marker{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:markerInfoContents:)]) {
        UCMarker *mmarker = [UCMarker markerWithPosition:marker.position];
        [mmarker setValue:marker forKey:@"marker"];
        return [self.mapDelegate mapView:_mapView markerInfoContents:mmarker];
    }
    return nil;
}
- (void)mapView:(GMSMapView *)mapView didCloseInfoWindowOfMarker:(GMSMarker *)marker{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:didCloseInfoWindowOfMarker:)]) {
        UCMarker *mmarker = [UCMarker markerWithPosition:marker.position];
        [mmarker setValue:marker forKey:@"marker"];
        [self.mapDelegate mapView:_mapView didCloseInfoWindowOfMarker:mmarker];
    }
}
- (void)mapView:(GMSMapView *)mapView didBeginDraggingMarker:(GMSMarker *)marker{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:didBeginDraggingMarker:)]) {
        UCMarker *mmarker = [UCMarker markerWithPosition:marker.position];
        [mmarker setValue:marker forKey:@"marker"];
        [self.mapDelegate mapView:_mapView didBeginDraggingMarker:mmarker];
    }
}
- (void)mapView:(GMSMapView *)mapView didEndDraggingMarker:(GMSMarker *)marker{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:didEndDraggingMarker:)]) {
        UCMarker *mmarker = [UCMarker markerWithPosition:marker.position];
        [mmarker setValue:marker forKey:@"marker"];
        [self.mapDelegate mapView:_mapView didEndDraggingMarker:mmarker];
    }
}
- (void)mapView:(GMSMapView *)mapView didDragMarker:(GMSMarker *)marker{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:didDragMarker:)]) {
        UCMarker *mmarker = [UCMarker markerWithPosition:marker.position];
        [mmarker setValue:marker forKey:@"marker"];
        [self.mapDelegate mapView:_mapView didDragMarker:mmarker];
    }
}

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker{
    if (self.mapDelegate && [self.mapDelegate respondsToSelector:@selector(mapView:didTapMarker:)]) {
        UCMarker *mmarker = [UCMarker markerWithPosition:marker.position];
        mmarker.userData = marker.userData;
        [mmarker setValue:marker forKey:@"marker"];
        return [self.mapDelegate mapView:_mapView didTapMarker:mmarker];
    }
    return YES;
}

@end
